import datetime
import logging
from uuid import uuid4

from captcha.models import CaptchaStore
from django.conf import settings
from django.contrib.auth import get_user_model
from django.core.cache import cache
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.views import TokenObtainPairView

from apps.vadmin.system.models.logininfor import LoginInfor
from apps.vadmin.utils.exceptions import GenException
from apps.vadmin.utils.request_util import get_request_ip, get_os, get_browser, get_login_location
from apps.vadmin.op_drf.response import SuccessResponse, ErrorResponse
from django.shortcuts import redirect

logger = logging.getLogger(__name__)

User = get_user_model()


class LogoutView(APIView):
    queryset = User.objects.all()
    permission_classes = (IsAuthenticated,)
    prefix = settings.SIMPLE_JWT.get('SIMPLE_JWT_HEADER_PREFIX', 'JWT')

    def post(self, request):
        user = request.user
        user.user_secret = uuid4()
        user.save()
        key = f"{self.prefix}_{user.username}"
        if getattr(settings, "REDIS_ENABLE", False):
            cache.delete(key)
        return SuccessResponse()

class LoginSerializer(TokenObtainPairSerializer):
    prefix = settings.SIMPLE_JWT.get('SIMPLE_JWT_HEADER_PREFIX', 'JWT')    
    def validate_captcha(self, request):
        """
        校验验证码
        :param request:
        :return:
        """
        if not settings.CAPTCHA_STATE:  # 未开启验证码则返回 True
            return True
        idKeyC = request.data.get('idKeyC', None)
        idValueC = request.data.get('idValueC', None)
        if not idValueC:
            raise GenException(message='请输入验证码')
        try:
            get_captcha = CaptchaStore.objects.get(hashkey=idKeyC)
            if str(get_captcha.response).lower() == idValueC.lower():  # 如果验证码匹配
                get_captcha.delete()
                return True
        except:
            pass
        else:
            if get_captcha: get_captcha.delete()
            raise GenException(message='验证码错误')

    def save_login_infor(self, request, msg='', status=True, session_id=''):
        
        User = get_user_model()
        instance = LoginInfor()
        instance.session_id = session_id
        instance.browser = get_browser(request)
        instance.ipaddr = get_request_ip(request)
        instance.loginLocation = get_login_location(request)
        instance.msg = msg
        instance.os = get_os(request)
        instance.status = status
        instance.creator = request.user and User.objects.filter(username=request.data.get('username')).first()
        instance.save()

    def validate(self, attrs): 
        request=self.context["request"]       
        username = attrs['username']
        password = attrs['password']
        self.validate_captcha(request)
        user = User.objects.filter(username=username).first()
        
        if user and user.check_password(password):  # check_password() 对明文进行加密,并验证
            data = super().validate(attrs)
            refresh = self.get_token(user)
            data['username'] = username
            data['userId'] = self.user.id
            data['refresh'] = str(refresh)
            data['token'] = str(refresh.access_token)
            token = refresh.access_token
            key = f"{self.prefix}_{token}_{username}"
            if getattr(settings, "REDIS_ENABLE", False):
                cache.set(key, refresh.access_token, self.ex.total_seconds())                     
            self.save_login_infor(request, '登录成功', session_id=token)
            result = {
                "code": 200,
                "status": 'success',
                "msg": "请求成功",
                "data": data
            }            
            return result
            
        else:
           #self.image_code.delete()
            result = {
                "code": 4000,
                "msg": "账号/密码不正确",
                "data": None
            }
        return result
    

class LoginView(TokenObtainPairView):
    serializer_class = LoginSerializer
   